#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.enums.service;


import java.util.Arrays;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;

public interface EnumsBaseService {
    /**
     * 获取编码
     * @return
     */
    String getCode();

    /**
     * 获取描述
     * @return
     */
    String getDesc();

    /**
     * 根据编码获取枚举
     * @param code
     * @param enumClass
     * @return
     * @param <T>
     */
    static <T extends Enum<T> & EnumsBaseService> T getEnumByCode(String code, Class<T> enumClass){
        return Arrays.stream(enumClass.getEnumConstants())
                .filter(e ->  e.getCode().equals(code))
                .findFirst()
                .orElse(null);

    }
    /**
     * 根据编码获取枚举并执行
     * @param code
     * @param enumClass
     * @param consumer
     * @param <T>
     */
    static <T extends Enum<T> & EnumsBaseService> void findEnumByCodeThenRun(String code, Class<T> enumClass, Consumer<T> consumer){
        T t = Arrays.stream(enumClass.getEnumConstants())
                .filter(e -> e.getCode().equals(code))
                .findFirst()
                .orElse(null);
        if(Objects.isNull(t)){
            return ;
        }
        consumer.accept(t);
    }
    /**
     * 根据编码获取枚举并执行
     * @param code
     * @param enumClass
     * @param function
     * @return
     * @param <T>
     * @param <R>
     */
    static <T extends Enum<T> & EnumsBaseService, R> R findEnumByCodeThenRunWithReturn(String code, Class<T> enumClass, Function<T, R> function){
        T t = Arrays.stream(enumClass.getEnumConstants())
                .filter(e -> e.getCode().equals(code))
                .findFirst()
                .orElse(null);
        if(Objects.isNull(t)){
            return null;
        }
        return function.apply(t);
    }



    /**
     * 枚举值是否相等
     * @param other
     * @return
     */
    default boolean eq(EnumsBaseService other){
        return this == other;
    }


    /**
     * 如果相等则执行
     * @param other
     * @param consumer
     * @param <T>
     */
    default <T extends Enum<T> & EnumsBaseService> void exeIfEq(T other, Consumer<T> consumer){
        if(eq(other)){
            consumer.accept(other);
        }
    }

    /**
     * 如果相等则执行
     * @param code
     * @param consumer
     * @param <T>
     */
    default <T extends Enum<T> & EnumsBaseService> void exeIfEq(String code, Consumer<T> consumer){
        T other = getEnumByCode(code, (Class<T>) this.getClass());
        exeIfEq(other, consumer);
    }


    /**
     * 如果相等则执行
     * @param other
     * @param function
     * @param <T>
     */
    default <T extends Enum<T> & EnumsBaseService, R> R exeIfEq(T other, Function<T,R> function){
        if(eq(other)){
            return function.apply(other);
        }
        return null;
    }
    /**
     * 如果相等则执行
     * @param code
     * @param function
     * @param <T>
     */
    default <T extends Enum<T> & EnumsBaseService, R> R exeIfEq(String code, Function<T, R> function){
        T other = getEnumByCode(code, (Class<T>) this.getClass());
        return exeIfEq(other, function);
    }
}
